package com.ztools.pc.service.impl.sys;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ztools.common.model.pc.login.LoginToken;
import com.ztools.common.model.pc.sys.User;
import com.ztools.common.util.common.PageUtil;
import com.ztools.common.util.common.ServiceException;
import com.ztools.common.util.common.TokenUtil;
import com.ztools.common.util.pc.RedisUtil;
import com.ztools.pc.async.SysAsync;
import com.ztools.pc.mapper.sys.UserMapper;
import com.ztools.pc.service.sys.RolePermissionService;
import com.ztools.pc.service.sys.UserRoleService;
import com.ztools.pc.service.sys.UserService;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Author:一口香菜
 * @Date: 2023/3/2  20:34
 * @Version 1.0
 */
@Transactional
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Lazy
    @Resource
    private SysAsync sysAsync;
    @Resource
    private TokenUtil tokenUtil;
    @Resource
    private UserRoleService userRoleService;
    @Resource
    private RolePermissionService rolePermissionsService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Page<User> findList(PageUtil<User> pageUtil) {
        List<OrderItem> orders = new ArrayList<>();
        QueryWrapper<User> queryWrapper = getQueryWrapper(pageUtil.getParams());
        Page<User> pages = new Page<>(pageUtil.getPage(), pageUtil.getSize());
        // 排序数据  StrUtil.toUnderlineCase huTools将驼峰装换为下划线格式
        orders.add(new OrderItem(StrUtil.toUnderlineCase(pageUtil.getSortName()), "asc".equals(pageUtil.getSortOrder())));
        pages.setOrders(orders);
        return page(pages, queryWrapper);
    }

    @Override
    public boolean delete(User user) {
        boolean b = false;
        User userById = getById(user.getId());
        b = removeById(user.getId());
        return b;
    }

    @Override
    public boolean add(User user) {
        boolean b = false;
        if (StrUtil.isEmpty(user.getPassword())) {
            // 默认密码
            user.setPassword(DigestUtil.md5Hex("123456"));
        } else {
            user.setPassword(DigestUtil.md5Hex(user.getPassword()));
        }
        return save(user);
    }

    @Override
    public boolean update(User user) {
        boolean b = false;
        // 修改前先获取，在删除（乐观锁）
        User userById = getById(user);
        b = updateById(user);
        return b;
    }

    @Override
    public boolean updatePwd(User user) {
        if (user.getPassword() == null) {
            throw new ServiceException("请填写新密码");
        }
        boolean b = false;
        // 修改前先获取，在删除（乐观锁）
        User userById = getById(user);
        user.setPassword(DigestUtil.md5Hex(user.getPassword()));
        b = updateById(user);
        return b;
    }

    @Override
    public List<User> findByObject(User user) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);
        return list(queryWrapper);
    }


    @Override
    public LoginToken login(User user) {
//        String key = RedisUtil.CACHE_REMEMBER_ME + user.getLoginName();
//        String rememberMeUser = stringRedisTemplate.opsForValue().get(key);
//        if (StrUtil.isNotEmpty(rememberMeUser)) {
//            User rememberUser = JSONUtil.toBean(rememberMeUser, User.class);
//            return tokenUtil.add(rememberUser);
//        }
//        stringRedisTemplate.delete(key);
        if (user.getLoginName().isEmpty()) {
            throw new ServiceException("账号不能为空");
        }
        if (user.getPassword().isEmpty()) {
            throw new ServiceException("密码不能为空");
        }
        // 判断是否有该账号
        user.setPassword(DigestUtil.md5Hex(user.getPassword()));
        QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);
        User use = getOne(queryWrapper);
//        if (user.getRememberMe()) {
//            stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(use), 1L, TimeUnit.HOURS);
//        }
        if (use != null) {
            //异步刷新登入时间
            sysAsync.doAfterUserLogin(use);
            return tokenUtil.add(use);
        }
        return null;
    }


    @Override
    public void logout(String token) {
        tokenUtil.delete(token);
    }

    @Override
    public User findByToken(String token) {
        LoginToken loginToken = tokenUtil.get(token);
        if (loginToken == null) {
            return null;
        }
        User user = getById(loginToken.getUserId());
        if (user != null) {
            stringRedisTemplate.opsForValue().set(RedisUtil.CURRUSER, JSONUtil.toJsonStr(user), 1, TimeUnit.HOURS);
            //设置角色列表
            user.setRoles(userRoleService.findRoleByUserId(user.getId()));
            //设置权限列表
            user.setPermissions(rolePermissionsService.findPerByRoleId(user.getId()));
        }
        return user;
    }

    @Override
    public User findUserByToken(String token) {
        LoginToken loginToken = tokenUtil.get(token);
        User user = User.builder().id(loginToken.getUserId()).build();
        return getById(user);
    }

    @Override
    public boolean restPassword(User user) {
        UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
        userUpdateWrapper.eq("id", user.getId()).set("password", DigestUtil.md5Hex("123456"));
        return update(userUpdateWrapper);
    }

    public QueryWrapper<User> getQueryWrapper(User user) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotEmpty(user.getShowName())) {
            queryWrapper.lambda().like(User::getShowName, user.getShowName());
        }
        if (StrUtil.isNotEmpty(user.getLoginName())) {
            queryWrapper.lambda().like(User::getLoginName, user.getLoginName());
        }
        if (StrUtil.isNotEmpty(user.getPhone())) {
            queryWrapper.lambda().like(User::getPhone, user.getPhone());
        }
        return queryWrapper;
    }

    /**
     * 字典翻译
     *
     * @param userList
     * @return
     */
    public List<User> dictionary(List<User> userList) {
        for (User user : userList) {
            dictionary(user);
        }
        return userList;
    }

    public void dictionary(User user) {

    }
}
